home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 013 / cddplus.arc / CDD.ASM next >
Encoding:
Assembly Source File  |  1987-05-03  |  9.0 KB  |  321 lines

  1.     page 60,132
  2.     title  CDD - Change Drive/Directory
  3.     name CDD
  4.  
  5. comment    #
  6.     CDD.COM                            V1.00
  7. -------------------------------------------------------------------------------
  8. NAME
  9.     cdd                Change drive and directory    
  10.     
  11. SYNOPSIS
  12.     CDD [D:][\PATH]
  13.     
  14.     where
  15.         D: is the desired destination drive
  16.         \PATH is the desired path
  17.         
  18.         both drive and path are optional.  If the command line is 
  19.         blank, a help message is printed on the screen.
  20.  
  21. DESCRIPTION
  22.     This program is a clone of Bruce B. Thomson program of the same name.
  23.     It will change the drive, directory, or both the drive and directory.
  24.     
  25.     This program is only command line driven.  If the command line is
  26.     blank, a quick message on how to properly evoke this program is
  27.     displayed on the screen.
  28.     
  29.     The program checks for the following errors:
  30.     a.  The terminal drive is not the same as the one requested.
  31.     b.  The termanal path is not the same as the one requested.
  32.     c.  The DOS version is 2.0 or above.
  33.     
  34.     In cases (a) and (b)  above, CDD will return you to the starting drive
  35.     and path. 
  36.     
  37. CAUTION
  38.     CDD does not check drive or path information before using it.
  39.     If the drive is changed to a floppy with the drive door open, the 
  40.     DOS Critical Error Handler is called.  A disk must be inserted in 
  41.     the drive before the DOS Critical Error Handler will relinquish the 
  42.     use of the computer to you.  (There is a way to avoid this.  Before 
  43.     changing drives, use the DOS Absolute Read interrupt to read a sector.
  44.     This interrupt does not evoke the Critical Error Handler so this error
  45.     can be caught before it happens.  The major problem is that this really
  46.     slows down the code because of the time it takes to read a sector.
  47.     I will leave the addition of this feature as a programming challange 
  48.     for the user.)
  49.     
  50. AUTHOR
  51.     Raymond Moon - 2 May 87
  52.     Copyright (c) 1987
  53.     ALL RIGHTS RESERVED
  54.  
  55. HISTORY
  56.     Version    - Date        - Comments
  57.     1.00      2 May 87    - Orginal
  58.     #
  59.     
  60. ;-------------------------------
  61. ;    Required equates and macros.
  62.  
  63. @EXIT    macro    RTNCODE            ;; Terminate program with return code
  64.     mov    ax,4c&RTNCODE&h        ; Request term with return code
  65.     int    21h            ; Call PC-DOS
  66.     endm
  67.  
  68. @WRITE    macro    STRING,FH        ;; DOS 2.0+ Write to File Macro
  69.     lea    dx,STRING        ; Load String addr in DX
  70.     mov    cx,STRING&_LEN        ; Load String Length in CX
  71.     mov    bx,FH            ; Load File Handle in BX
  72.     mov    ah,40h            ; Request DOS write to file/device
  73.     int    21h            ; Call PC-DOS
  74.     endm
  75.  
  76.     STDOUT    equ    1
  77.     TAB    equ    9
  78.     LF    equ    0ah
  79.     CR    equ    0dh
  80.     _MASK    equ    0dfh
  81.     BLNK    equ    ' '
  82.         
  83. GRP    group    CSEG,DSEG,STRING        ; All segments in same segment
  84.     assume    cs:GRP,ds:GRP,es:GRP,ss:GRP
  85.     
  86.     subttl Data Segments
  87.     page
  88.  
  89. STRING    segment word public 'CONST'
  90.     public DOS_ERR, INVALID_DRIVE,BAD_PATH,LOGO
  91.     public HELP
  92. DOS_ERR        db    'Need  DOS2.0+$'
  93. INVALID_DRIVE    db    'Invalid Drive Specification.'
  94. INVALID_DRIVE_LEN equ    $ - INVALID_DRIVE
  95. BAD_PATH    db    'Path Not Found.'
  96. BAD_PATH_LEN    equ    $ - BAD_PATH
  97. LOGO        db    'CDD - Change Drive/Directory',CR,LF
  98.         db    'Copyright (c) 1987 MoonWare',CR,LF,LF
  99. LOGO_LEN    equ    $ - LOGO
  100. HELP        db    'Evoke CDD with the following command line:',CR,LF,LF
  101.         db    TAB,'CDD [D:][\PATH]',CR,LF
  102.         db    TAB,TAB,'where',LF,TAB
  103.         db    'D: is the desired drive, optional',CR,LF
  104.         db    TAB,TAB,TAB,'\PATH is the desired path, optional',CR,LF
  105. HELP_LEN    equ    $ - HELP
  106.         db    '***** Raymond Moon - 28 Apr 87 *****'
  107. STRING    ends
  108.  
  109. DSEG    segment    word public 'DATA'
  110.     public CURRENT_DRIVE
  111. CURRENT_DRIVE    db    ?
  112. DSEG    ends
  113.  
  114.     subttl  Code Segment
  115.     page
  116. CSEG    segment para public 'CODE'
  117.  
  118. ;-----------------------------
  119. ;    Define ARGC, ARGV
  120.  
  121. PARM    struc                 ; Passed parameter addressing
  122.     dw    ?,?            ; Saved IP and BP
  123. ARGC    dw    ?            ; Number of parameters passed
  124. ARGV    dw    ?            ; Array of pointers.
  125. PARM    ends
  126.  
  127. ;-----------------------------
  128. ;    Define all procedures as public for debugging
  129.  
  130.     public MAIN, CMDLN, PRINT_HELP
  131.  
  132. ;-----------------------------
  133. ;    Define Command Line arguments located in the PSP
  134.  
  135.     org     80h
  136.     PARM_LEN db     ?
  137.     PARMS   db      127 dup(?)
  138.  
  139. ;-----------------------------
  140. ;    MAIN procedure parses the Command Line 
  141.  
  142.     org    100h            ; .COM file format
  143.  
  144. MAIN    proc    far
  145.     mov    ah,30h            ; Request DOS version
  146.     int    21h            ; Call DOS
  147.     cmp    al,2            ; Is it DOS 2.0+
  148.     jae    MN0            ; Yes, continue
  149.     lea    dx,DOS_ERR        ; DX => Error message
  150.     mov    ah,9            ; Request print string
  151.     int    21h            ; Call DOS
  152.     int    20h            ; Terminate program
  153. MN0:    cmp    PARM_LEN,0        ; Are there any Command Line arguments
  154.     jne    MN1            ; Yes, process them
  155.     call    PRINT_HELP        ; No, go print HELP 
  156. MN1:    xor    cx,cx            ; Null CX
  157.     push    cx            ; This ensures last *argv ends in NUL
  158.     mov    cl,PARM_LEN        ; Get # of bytes in Command Line
  159.     inc    cl            ; Increment CL to ensure round up
  160.     and    cx,0feh            ; Force an even count
  161.     mov    ax,sp            ; Get SP  
  162.     mov    bp,sp            ; Set BP to last byte of Cmd Ln
  163.     sub    ax,cx            ; Subtract PARM_LEN
  164.     mov    sp,ax            ; Reset SP, room on Stack
  165.     lea    si,PARMS        ; Load source addr in SI
  166.     mov    di,sp            ; Load destin addr in DI
  167.     cld                ; Ensure Direction Flag is up
  168.     rep    movsb            ; Move Command Line onto the Stack
  169.  
  170. ;-----------------------------
  171. ;    Convert all blanks in the Command Line to Nul
  172.  
  173.     mov    bx,bp            ; BX points to last byte of Cmd Ln
  174. MN2:    mov    al,[bx]            ; Get byte
  175.     cmp    al,BLNK            ; Is it a blank?
  176.     ja    MN3            ; No, go set up to get another
  177.     xor    al,al            ; Nul AX
  178.     mov    [bx],al            ; Store Nul in [BX]
  179. MN3:    dec    bx            ; BX point to next byte
  180.     cmp    bx,sp            ; Are we through yet?
  181.     jnb    MN2            ; No, go one mo' 'gin
  182.                     
  183. ;-----------------------------
  184. ;    Build *argv[].  argc kept in CX.  DX used as IN_WORD flag
  185.  
  186.     xor    cx,cx            ; Set CX (argc) to 0
  187.     xor    dx,dx            ; Set DX to NOT_INWORD
  188.     mov    bx,bp            ; BX point to last byte
  189.     mov    bp,sp            ; BP now points to Top of Stack
  190. MN4:    mov    al,[bx]            ; Get byte
  191.     cmp    al,0            ; Is it Nul?
  192.     jne    MN5            ; No, it is a char
  193.     cmp    dx,0            ; Was the last byte not a char?
  194.     je    MN6            ; Yes, go on with the processing
  195.     xor    dx,dx            ; No, it was a char.  Clear INWORD.
  196.     inc    cx            ; Increment argc
  197.     inc    bx            ; BX points to Cmd Ln arg
  198.     push    bx            ; Push addr onto stack
  199.     dec    bx            ; Reset BX
  200.     jmp    short MN6        ; Go set up for another byte
  201. MN5:    inc    dx            ; Set DX to INWORD     
  202. MN6:    dec    bx            ; BX point to next byte
  203.     cmp    bx,bp            ; Are we at the 1st byte yet?
  204.     jnb    MN4            ; No, go process another
  205.  
  206. ;-----------------------------
  207. ;    Set up for and call CMDLN
  208.  
  209.     push    cx            ; Push ARGC onto stack
  210.     call    CMDLN            ; Call Cmd Ln processor
  211. MAIN    endp
  212.  
  213.     public    PRINT_HELP
  214. PRINT_HELP    proc    near
  215.     @WRITE    HELP,STDOUT        ; Print help
  216.     @EXIT    01
  217. PRINT_HELP    endp
  218.  
  219.     public    CMDLN
  220. CMDLN    proc    near
  221.     push    bp            ; Save bp
  222.     mov    bp,sp            ; Set up frame pointer
  223.  
  224. ;----------------------------
  225. ;    Print LOGO
  226.  
  227.     @WRITE    LOGO,STDOUT        ; Print LOGO
  228.  
  229. ;----------------------------
  230. ;    Find ':', break string into drive and path, set flags.
  231.  
  232.     mov    di,[bp].ARGV        ; ES:DI => command line drive:path
  233.     mov    al,':'            ; AL = ':'
  234.     mov    cx,64            ; Max, count
  235.     repne    scasb            ; Find  ':'
  236.     cmp    cx,0            ; Is there a ':'
  237.     jnz    CN1            ; ':' found
  238.  
  239. ;-----------------------------
  240. ;    No ':' found => no drive specification.  Go change path.
  241.  
  242.     mov    dx,[bp].ARGV        ; DS:DX  => path
  243.     mov    ah,3bh            ; Request change current directory
  244.     int    21h            ; Call DOS
  245.     jc    CN0            ; No error, continue
  246.     @EXIT    00            ; Exit
  247.  
  248. ;----------------------------
  249. ;    Error in changing path, tell user.
  250.     
  251. CN0:    mov    dl,CURRENT_DRIVE    ; DL = old drive
  252.     mov    ah,0eh            ; Request select disk
  253.     int    21h            ; Call DOS
  254.     @WRITE    BAD_PATH,STDOUT        ; Tell user
  255.     @EXIT    02            ; Exit
  256.  
  257. ;-----------------------------
  258. ;    Change drive.  First get current drive.
  259.  
  260. CN1:    mov    ah,19h            ; Request current drive
  261.     int    21h            ; Call DOS
  262.     mov    CURRENT_DRIVE,al    ; Save it
  263.     mov    si,[bp].ARGV        ; SI = drive
  264.     and    byte ptr [si],_MASK    ; Convert to upper case
  265.     mov    dl,byte ptr [si]    ; DL = drive letter
  266.     sub    dl,'A'            ; Convert to drive specification
  267.     mov    ah,0eh            ; Request select disk
  268.     int    21h            ; Call DOS
  269.  
  270. ;----------------------------
  271. ;    Determine if error occurred by comparing current drive with desired
  272. ;    drive.
  273.  
  274.     mov    ah,19h            ; Request current drive
  275.     int    21h            ; Call DOS
  276.     cmp    al,dl            ; Are they equal?
  277.     je    CN2            ; Yes, go change path
  278.         
  279. ;----------------------------
  280. ;    Error changing drive.  Revert to old drive.
  281.  
  282.     mov    dl,CURRENT_DRIVE    ; DL = old drive
  283.     mov    ah,0eh            ; Request select disk
  284.     int    21h            ; Call DOS
  285.  
  286. ;--------------------------
  287. ;    Tell user of error and exit.
  288.  
  289.     @WRITE    INVALID_DRIVE,STDOUT    ; Write error message
  290.     @EXIT    02            ; Exit with error code 2
  291.  
  292. ;-----------------------------
  293. ;    See if there is a path.
  294.  
  295. CN2:    cmp    byte ptr [di],0            ; Is it EOS
  296.     je    CN3            ; Yes, go terminate
  297.     
  298. ;-----------------------------
  299. ;    Change of drive OK, go change path.
  300.  
  301.     mov    dx,di            ; DS:DX  => path
  302.     mov    ah,3bh            ; Request change current directory
  303.     int    21h            ; Call DOS
  304.     jc    CN4            ; No error, continue
  305. CN3:    @EXIT    00            ; Exit
  306.     
  307. ;----------------------------
  308. ;    Return to orginal drive, and tell user of problem.
  309.  
  310. CN4:    mov    dl,CURRENT_DRIVE    ; DL = old drive
  311.     mov    ah,0eh            ; Request select disk
  312.     int    21h            ; Call DOS
  313.     @WRITE    BAD_PATH,STDOUT        ; Tell user
  314.     @EXIT    02            ; Exit
  315.  
  316. CMDLN    endp
  317.  
  318. CSEG    ends
  319.  
  320.     end    MAIN
  321.